/*
 * =====================================================================================
 *
 *       Filename:  main.cpp
 *
 *    Description:  main.cpp
 *
 *         Author:  Younghyun Jo
 *   Organization:  Master Student
 *                  Computer Systems and Platforms Laboratory
 *                  Seoul National University
 *
 * =====================================================================================
 */
#include "epcc.h"
#include "stack.h"

////////////////////////////////////////////////////////////////////////////////////////
// CStack Options
// 1: CCoarseGrainedLockStack (PthreadLock)
// 2: CLockFreeStack (CAS)
// 3: CEliminationBackoffStack (capacity:, timeout:)
// 4: CCoarseGrainedTransactionalMemory
// 5: CLockFreeTransactionalMemory
// 6: CEliminationBackoffTransactionalMemory

int main(int argc, char* argv[])
{
  if (argv[1]==NULL || argv[2]==NULL || argv[3]==NULL || argv[4]==NULL || argv[5]==NULL) {
    printf("[Usage] ./test_stack [Stack] [numParticipants] [pushRatio] [numOperations] [Operation interval]\n");
    return 1;
  }

  int numParticipants = atoi(argv[2]);
  double pushRatio = atof(argv[3]);
  uint64_t numOperations = atol(argv[4]);
  unsigned long intervalOperation = atol(argv[5]);
  printf("numParticipants: %d pushRatio: %lf numOperations: %lu intervalOperation: %lu\n",
          numParticipants, pushRatio, numOperations, intervalOperation);

  int option = atoi(argv[1]);
  if (option == 0) {
    /* Benchmark for CCoarseGrainedLockStack */
    printf("\n[CTransactionalMemory Benchmark]\n");
    EPCC<CTransactionalMemory> epcc(numParticipants, pushRatio, numOperations, intervalOperation);
    epcc.measureCStackPerformance();

  } else if (option == 1) {
    /* Benchmark for CCoarseGrainedLockStack */
    printf("\n[CCoarseGrainedLockStack Benchmark]\n");
    EPCC<CCoarseGrainedLockStack> epcc(numParticipants, pushRatio, numOperations, intervalOperation);
    epcc.measureCStackPerformance();

  } else if (option == 2) {
    /* Benchmark for CLockFreeStack */
    printf("\n[CLockFreeStack Benchmark]\n");
    EPCC<CLockFreeStack> epcc2(numParticipants, pushRatio, numOperations, intervalOperation);
    epcc2.measureCStackPerformance();

  } else if (option == 3) {
    /* Benchmark for CEliminationBackoffStack */
    printf("\n[CEliminationBackoffStack Benchmark]\n");
    EPCC<CEliminationBackoffStack> epcc3(numParticipants, pushRatio, numOperations, intervalOperation);
    epcc3.measureCStackPerformance();

  } else if (option == 4) {
    /* Benchmark for CCoarseGrainedTransactionalMemory Stack */
    printf("\n[CCoarseGrainedTransactionalMemory Benchmark]\n");
    EPCC<CCoarseGrainedTransactionalMemory> epcc(numParticipants, pushRatio, numOperations, intervalOperation);
    epcc.measureCStackPerformance();

  } else if (option == 5) {
    /* Benchmark for CLockFreeTransactionalMemory Stack */
    printf("\n[CLockFreeTransactionalMemory Benchmark]\n");
    EPCC<CLockFreeTransactionalMemory> epcc(numParticipants, pushRatio, numOperations, intervalOperation);
    epcc.measureCStackPerformance();

  } else if (option == 6) {
    /* Benchmark for CEliminationBackoffTransactionalMemory Stack */
    printf("\n[CEliminationBackoffTransactionalMemory Benchmark]\n");
    EPCC<CEliminationBackoffTransactionalMemory> epcc(numParticipants, pushRatio, numOperations, intervalOperation);
    epcc.measureCStackPerformance();

  } else {
    printf("unexpected option.. cstack class...\n");
  }

  /* Benchmark for CCombTreeStack */
  //printf("\n[CCombTreeStack Benchmark]\n");
  //EPCC<CCombTreeStack> epcc(numParticipants, pushRatio, numOperations, intervalOperation);
  //epcc.measureCStackPerformance();

  return 0;
}

